package com.david.course_design.shopping_center.module.shoppingCart.service.impl;

import com.david.course_design.shopping_center.module.goods.goods.entity.Goods;
import com.david.course_design.shopping_center.module.goods.goods.service.GoodsService;
import com.david.course_design.shopping_center.module.shoppingCart.entity.ShoppingCart;
import com.david.course_design.shopping_center.module.shoppingCart.entity.VO.ShoppingCartItemVo;
import com.david.course_design.shopping_center.module.shoppingCart.entity.VO.ShoppingCartVo;
import com.david.course_design.shopping_center.module.shoppingCart.mapper.ShoppingCartMapper;
import com.david.course_design.shopping_center.module.shoppingCart.service.ShoppingCartService;
import com.david.course_design.shopping_center.result.PageObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {
    // 依赖注入(DI) dependency injection
    @Resource
    private ShoppingCartMapper shoppingCartMapper;

    @Resource
    private GoodsService goodsService;

    /**
     * 查询当前用户的所有购物车记录（分页）
     *
     * @param userId     当前用户的主键（userId）
     * @param pageObject 分页对象（包含pageNum(当前第几页)和pageSize(每页数据的条数)）
     * @return
     */
    @Override
    public PageInfo<ShoppingCart> CurrentUserSelectAllShoppingCartItemByPaging(Integer userId, PageObject pageObject) {
        PageHelper.startPage(pageObject.getPageNumber(), pageObject.getPageSize());

        // 创建分页对象
        PageInfo<ShoppingCart> shoppingCartPageInfo = new PageInfo<>(shoppingCartMapper.selectAllShoppingCartItemByUserId(userId));

        //  输出日志
        System.out.println(shoppingCartPageInfo);

        return shoppingCartPageInfo;
    }

    /**
     * 添加商品到当前用户的购物车中
     *
     * @param userId         当前用户的主键（userId）
     * @param shoppingCartVo 需要添加到用户购物车的商品的对象（shoppingCartVo）
     * @return -1:该数据已经在数据库中存在了； 1:添加成功 ； 0:添加失败
     */
    @Override
    @Transactional  //  @Transactional 该注释表示当前类为一个事务，具有原子性（涉及多表查修修改数据必须具有原子性），要不就全部执行，要不就不执行
    public Integer addGoodsItemToCurrentUserShoppingCartByGoodsId(Integer userId, ShoppingCartVo shoppingCartVo) {
//        System.out.print("addGoodsItemToCurrentUserShoppingCartByGoodsId ==> ");
        //  查询当前商品是否已经在购物车中
        boolean goodsIsInShoppingCartByGoodsId = selectCurrentGoodsIsInShoppingCartByGoodsId(userId, shoppingCartVo.getGoodsId());

        if (goodsIsInShoppingCartByGoodsId) {
            //  如果当前商品已经在当前用户的购物车中则直接返回
            System.out.println("该商品已经在数据库中存在记录了（该用户已经添加过该商品到数据库了）");
            return -1;
        }

        //  创建待插入数据库的数据对象
        ShoppingCart shoppingCart = new ShoppingCart();

        //  设置插入对象的各个属性的值
        shoppingCart.setUserId(userId); //  设置对象的用户id（userId）
        shoppingCart.setGoodsId(shoppingCartVo.getGoodsId()); // 设置对象的商品id（goodsId）
        shoppingCart.setGoodsNumber(shoppingCartVo.getGoodsNumber()); // 设置用户的商品数量（goodsNumber）

        // 如果当前用户还未将当前商品添加到购物车中，则将当前的商品添加到当前用户的购物车中
        int insert = shoppingCartMapper.insert(shoppingCart);

        //  通过返回的主键查询到数据库中的记录
        ShoppingCart selectShoppingCartItemByUserIdAndGoodsId = shoppingCartMapper.selectShoppingCartItemByUserIdAndGoodsId(userId, shoppingCartVo.getGoodsId());

        //  输出日志
        System.out.println("插入数据库的记录为 ==> " + selectShoppingCartItemByUserIdAndGoodsId.toString());

        // 如果插入操作之后查询数据库返回的记录不为空 1 ;否则返回0
        return insert;
    }

    /**
     * 通过商品主键删除当前用户购物车中的商品
     *
     * @param userId  当前用户的主键（userId）
     * @param goodsId 当前需要从购物车中删除的商品的主键（goodsId）
     * @return 返回数据库受影响的行数
     */
    @Override
    @Transactional  // 标记改类为一个事务，具有原子性，不能分解只能完全执行或不执行
    public Integer deleteGoodsItemFromCurrentUserShoppingCartByGoodsId(Integer userId, Integer goodsId) {
//        System.out.print("deleteGoodsItemFromCurrentUserShoppingCartByGoodsId ==> ");
        //  通过查询数据库，找到数据库中的记录
        ShoppingCart shoppingCart = selectShoppingCartItemByUserIdAndGoodsId(userId, goodsId);

        //  如果查询数据库返回的对象不为空
        if (shoppingCart != null) {
            // 输出日志
            System.out.println("需要删除的数据库中的记录为 ==> " + shoppingCart.toString());

            //  执行删除操作并获取数据库返回的数据库受影响的行数
            int delete = shoppingCartMapper.delete(shoppingCart);

            //  返回数据库受影响的行数
            return delete;

        }

        //  如果查询数据库操作返回的对象为空，则直接返回 0 ，表示数据库中没有这个记录（虽然不会执行，但是不能删除）
        return 0;
    }

    /**
     * 通过商品主键（goodsId）查询当前商品是否已经添加到当前用户的购物车中
     *
     * @param userId  当前用户的主键（userId）
     * @param goodsId 当前的商品的主键（goodsId）
     * @return 返回一个布尔值 ==> true:当前商品已经被添加到了当前用户的购物车中; false: 表示当前商品还未添加到当前用户的购物车
     */
    @Override
    public boolean selectCurrentGoodsIsInShoppingCartByGoodsId(Integer userId, Integer goodsId) {
//        System.out.print("selectCurrentGoodsIsInShoppingCartByGoodsId ==> ");
        //  查询数据库，接受返回的数据对象
        ShoppingCart shoppingCart = selectShoppingCartItemByUserIdAndGoodsId(userId, goodsId);

        //  如果数据对象不为空
        if (shoppingCart != null) {
            // 输出日志
            System.out.println("查询出当前的商品在数据库的记录为 ==> " + shoppingCart.toString());

            //  返回数据对象存在（true）
            return true;
        }
        //  返回数据对象不存在（false）
        return false;
    }

    /**
     * 通过用户主键id和商品主键查询购物车中商品的信息
     *
     * @param userId  用户主键 （userId）
     * @param goodsId 商品主键 （goodsId）
     * @return 返回查询到的数据库记录（数据库中商品条目并非商品的具体信息，如果需要查询商品的具体信息还需要通过商品的主键（goodsId）查询商品信息表获取商品信息）
     */
    @Override
    public ShoppingCart selectShoppingCartItemByUserIdAndGoodsId(Integer userId, Integer goodsId) {
//        System.out.print("selectShoppingCartItemByUserIdAndGoodsId ==> ");
        //  执行查询操作，并获取数据库返回的对象
        ShoppingCart shoppingCart = shoppingCartMapper.selectShoppingCartItemByUserIdAndGoodsId(userId, goodsId);

        //  如果返回的对象不为空
        if (shoppingCart != null) {
            //  输出日志
            System.out.println("通过用户 id 和商品 id 查询出来的数据库记录 ==> " + shoppingCart.toString());

            //  返回查询出的结果
            return shoppingCart;
        }

        //  返回空，表示数据库中没有该条记录
        return null;
    }

    /**
     * 通过用户主键 id 和商品主键 id 修改购物车中记录中的 商品的数量
     *
     * @param userId      用户主键 id
     * @param goodsId     商品主键 id
     * @param goodsNumber 商品数量
     * @return 返回数据库中受影响的行数
     */
    @Override
    @Transactional
    public Integer updateShoppingCartItemGoodsNumberByUserIdAndGoodsId(Integer userId, Integer goodsId, Integer goodsNumber) {
        //  将数据库中的购物车中的记录查询出来
        ShoppingCart shoppingCart = selectShoppingCartItemByUserIdAndGoodsId(userId, goodsId);

        //  找到商品的数量
        String shoppingCartGoodsNumber = shoppingCart.getGoodsNumber();

        if (Integer.parseInt(shoppingCartGoodsNumber) != goodsNumber) {
            //  创建新的购物车记录
            ShoppingCart shoppingCart1 = new ShoppingCart();

            shoppingCart1.setId(shoppingCart.getId());
            shoppingCart1.setGoodsNumber(goodsNumber + "");
            shoppingCart1.setUserId(userId);
            shoppingCart1.setGoodsId(goodsId);

            //  执行数据库更新
            int updateByPrimaryKey = shoppingCartMapper.updateByPrimaryKey(shoppingCart1);

            //  输出日志
            System.out.println("初始的数据库记录 ==> " + shoppingCart.toString());
            System.out.println("新的数据库记录 ==> " + shoppingCart1.toString());

            return updateByPrimaryKey;
        }

        return null;
    }

    /**
     * 查询当前用户的购物车中的商品条目和商品的信息
     *
     * @param userId     当前用户的主键（userId）
     * @param pageObject 分页对象（包含pageNum(当前第几页)和pageSize(每页数据的条数)）
     * @return 返回当前用户购物车中的所有商品和商品的详细信息
     */
    @Override
    @Transactional /* 标记当前方法为一个事务，不可分割，要不执行完全，要不不执行，具有原子性 */
    public PageInfo<ShoppingCartItemVo> selectShoppingCartItemByPaging(Integer userId, PageObject pageObject) {
        PageHelper.startPage(pageObject.getPageNumber(), pageObject.getPageSize());

        //  查询购物车中的商品
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.selectAllShoppingCartItemByUserId(userId);

        //  返回给前端的数据
        List<ShoppingCartItemVo> shoppingCartItemVos = new ArrayList<>();

        //  遍历所有购物车中的商品
        for (int i = 0; i < shoppingCarts.size(); i++) {
            //  每一个购物车中的商品
            ShoppingCart shoppingCart = shoppingCarts.get(i);

            //  获取每一个购物车中商品的商品主键（goodsId）
            Integer goodsId = shoppingCart.getGoodsId();

            //  通过商品的主键，查询商品的详细信息
            Goods goods = goodsService.selectGoodsById(goodsId);

            //  组装数据（将数据的数据结构转换为前端指定的数据结构）
            ShoppingCartItemVo shoppingCartItemVo = new ShoppingCartItemVo();

            //  设置主键
            shoppingCartItemVo.setId(goodsId);

            //  设置商品展示的图片
            shoppingCartItemVo.setImg_url(goods.getImgUrl());

            //  设置商品名称（商品描述）
            shoppingCartItemVo.setDescribe(goods.getName());

            //  设置商品的价格
            shoppingCartItemVo.setPrice(Double.parseDouble(goods.getPrice()));

            //  设置商品在购物车中的数量
            shoppingCartItemVo.setNumber(Integer.parseInt(shoppingCart.getGoodsNumber()));

            //  将组装好的数据添加到需要返回的数据集合中
            shoppingCartItemVos.add(shoppingCartItemVo);
        }

        //  创建分页对象
        PageInfo<ShoppingCartItemVo> shoppingCartItemVoPageInfo = new PageInfo<>(shoppingCartItemVos);

        //  输出日志
        System.out.println(shoppingCartItemVoPageInfo);

        //  返回处理后的结果
        return shoppingCartItemVoPageInfo;
    }
}
